﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace Devonline.AspNetCore;

/// <summary>
/// 全局异常处理过滤器
/// </summary>
public class ExceptionFilter(ILogger<ExceptionFilter> logger) : IAsyncExceptionFilter
{
    private readonly ILogger<ExceptionFilter> _logger = logger;

    /// <summary>
    /// 异常处理方法
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task OnExceptionAsync(ExceptionContext context)
    {
        if (!context.ExceptionHandled)
        {
            var message = "服务器内部错误";
            var response = context.HttpContext.Response;
            response.StatusCode = StatusCodes.Status500InternalServerError;
            var errorMessage = context.Exception.GetMessage();
            _logger.LogError(errorMessage);

            switch (context.Exception)
            {
                case BadHttpRequestException:
                    //业务类型的错误需要抛出 BadHttpRequestException 异常, 一律按 BadRequest(400) 处理
                    response.StatusCode = StatusCodes.Status400BadRequest;
                    message = context.Exception.Message;
                    break;
                case UnauthorizedAccessException:
                    response.StatusCode = StatusCodes.Status401Unauthorized;
                    message = "用户尚未登陆, 请先登录!";
                    break;
                case DbUpdateException:
                    //数据存在依赖不可删除时
                    response.StatusCode = StatusCodes.Status400BadRequest;
                    message = "当前数据正在使用中, 不能删除, 请先删除正在使用此数据的依赖数据, 在尝试删除当前数据!";
                    break;
            }

#if DEBUG
            message = errorMessage;
#endif

            context.Result = new JsonResult(message);
            context.ExceptionHandled = true;
        }

        return Task.CompletedTask;
    }
}
